// ## 2023/09/01 # 黑店小小二 # 修复生产数量过多 ##
// ## 2023/05/03 # 江东新风 # 函数主体自305迁回,改进公式以适应执政官 ##
// ## 2022/11/01 # 铃 # 在新的自动化内政中,生产也成为自动化,为新的内政系统设定参数和算法 ##
// ## 2022/08/14 # 铃 # 在新的人口系统中,生产的逻辑也发生了很大变化,重做相关函数。 ##
// ## 2021/10/01 # 江东新风 # namespace的韩文改成英文 ##
// ## 2021/09/15 # 江东新风 # 更改pk::core[]函数为英文##
// ## 2020/10/23 #江东新风#同步马术书大神的更新，修复战役模式情况的nullptr错误##
// ## 2020/08/24 # 氕氘氚 # 常量修改 ##
// ## 2020/08/16 #江东新风#has_skill函数替換##
/*
@수정자 : 기마책사
@Update: '19.05.4   // 수정내용: 유저_도시수_패널티 추가
@Update: '20.8.29  // 수정내용: 캠페인에서는 커스텀 세팅 사용 불가하도록 수정
*/

namespace PRODUCE
{
	//---------------------------------------------------------------------------
	// ================ 自动内政全局常量================

	const bool 玩家_城市数_惩罚 = false; // 유저세력에 대해서 도시수에 비례하여 생산량 디버프 (도시당 1% 감소)

	//---------------------------------------------------------------------------

	class Main
	{

		Main()
		{
			pk::set_func(102, pk::func102_t(callback));
		}

		int callback(pk::city @city, const pk::detail::arrayptr<pk::person @> &in actors, int weapon_id)
		{
			pk::list<pk::person @> actor_list;
			for (int i = 0; i < actors.length; i++)
			{
				actor_list.add(actors[i]);
			}
			return cal_produce_gain(pk::city_to_building(city), actor_list, weapon_id);
		}
		float func_5c7040(pk::city @city, int weapon_id)
		{
			int level1 = 0, level2 = 0;
			if (weapon_id == 兵器_枪 or weapon_id == 兵器_戟 or weapon_id == 兵器_弩)
			{
				for (int i = 0; i < city.max_devs; i++)
				{
					pk::building @building = city.dev[i].building;
					if (pk::is_alive(building))
					{
						switch (building.facility)
						{
						case 设施_锻冶1级:
							building.completed ? level1++ : 0;
							break;
						case 设施_锻冶2级:
							building.completed ? level2++ : level1++;
							break;
						case 设施_锻冶3级:
							building.completed ? 0 : level2++;
							break;
						}
					}
				}
				if (int(city.blacksmith_counter) > level1 + level2)
					return 1.5f;
				if (int(city.blacksmith_counter) > level1)
					return 1.2f;
			}
			else if (weapon_id == 兵器_战马)
			{
				for (int i = 0; i < int(city.max_devs); i++)
				{
					pk::building @building = city.dev[i].building;
					if (pk::is_alive(building))
					{
						switch (building.facility)
						{
						case 시설_마구간:
							building.completed ? level1++ : 0;
							break;
						case 시설_마구간2단:
							building.completed ? level2++ : level1++;
							break;
						case 시설_마구간3단:
							building.completed ? 0 : level2++;
							break;
						}
					}
				}
				if (int(city.stable_counter) > level1 + level2)
					return 1.5f;
				if (int(city.stable_counter) > level1)
					return 1.2f;
			}
			return 0.3f;
		}

	} Main main;

	int cal_produce_gain(pk::building @base, pk::list<pk::person @> actors, int weapon_id)
	{
		if (actors[0] is null)
			return 0;
		if (!pk::is_valid_equipment_id(weapon_id))
			return 0;
		if (weapon_id >= 兵器_冲车)
			return 1;

		int n = 0, sum = 0, max = 0, skill_id = -1;
		int mul = 100, pro = 100;

		pk::force @force = pk::get_force(base.get_force_id());

		if (weapon_id <= 兵器_弩)
		{
#if param_set
			skill_id = pk::get_produce_param().smith_skill; // int(pk::core["weapon_produce.smith_skill"]);
#endif
#if not_param_set
			skill_id = int(pk::core["weapon_produce.smith_skill"]);
#endif
			pro = 制造数量倍率;
		}
		else if (weapon_id == 兵器_战马)
		{
#if param_set
			skill_id = pk::get_produce_param().stable_skill; // int(pk::core["weapon_produce.stable_skill"]);

#endif
#if not_param_set
			skill_id = int(pk::core["weapon_produce.stable_skill"]);
#endif
			pro = 军马数量倍率;
		}
		bool has_skill = false;
		for (int i = 0; i < actors.count; i++)
		{
			pk::person @actor = actors[i];
			if (pk::is_alive(actor))
			{
#if param_set
				int s = actor.stat[pk::get_produce_param().stat]; // actor.stat[int(pk::core["weapon_produce.stat"])];
#endif
#if not_param_set
				int s = actor.stat[int(pk::core["weapon_produce.stat"])];
#endif
				// pk::trace("produce stat:" + s);
				// 此处应引入内政经验概念来抵消人数多的优势
				sum = sum + s;
				max = pk::max(max, s);
				if (ch::has_skill(actor, skill_id))
					has_skill = true;
			}
		}

		if (has_skill)
			mul += pk::core::skill_constant_value(skill_id);

		if (weapon_id == 兵器_战马 and city_tech::is_force_has_city(force, 2))
			mul += 10;

		if (weapon_id <= 兵器_弩 and city_tech::is_force_has_city(force, 33))
			mul += 10;

		float facility_eff = pk::is_valid_city_id(base.get_id()) ? main.func_5c7040(pk::building_to_city(base), weapon_id) : 1.1f;

		float exp_eff = 1.0f;
		float absent_eff = 1.0f;
		float expend_eff = 1.0f;
		if (auto_inner::is_auto_affairs(base, actors)) // 只有在人数为1，开启自动内政，且有执政官经验时享受加成
		{
			int rank_type = weapon_id == 兵器_战马 ? 内政自动化_育马 : 内政自动化_兵装;
			// exp_eff = main.get_exp_eff(actors[0].get_id(), weapon_id);
			exp_eff = auto_inner::get_exp_eff(actors[0].get_id(), rank_type);
			absent_eff = auto_inner::get_absent_eff(actors[0], rank_type);

			auto building_p = ch::get_baseIA(base.get_id());
			int effic = (weapon_id == 兵器_战马) ? building_p.horse_effic : building_p.weapon_effic;
			float rate = float(effic) / pk::get_equipment(weapon_id).gold_cost * 1.2; // 执政官经验倍率由于无法互动而降低了,在这里暂时补上这部分损失的值
			expend_eff = pk::min(2.0f, rate);
		}
		// 防止武将255政治的时候出现意外数值.对sum+max进行约束
		//  n = int((sum + max + 200) * 5 * mul / 100 * pro / 100 * facility_eff);
		n = int((350 + pk::max(200,pk::min(500, sum + max + 100)) * exp_eff * 5.0) * mul / 100 * pro / 100 * facility_eff * absent_eff * expend_eff);
		//pk::trace(pk::format("是否已行动{},sum{},max{},exp_eff{},mul{},pro{},facility_eff{},absent_eff{},expend_eff{}",actors[0].action_done,sum,max,exp_eff,mul,pro,facility_eff,absent_eff,expend_eff));

		if (pk::enemies_around(base))
			n = n * 兵临城下时生产倍率 / 100;

		// 难度修正
		n = int(n * (base.is_player() ? 100 : inter::domestic_difficulty_impact()) / 100.f);

		// 玩家电脑区别对待
		n = int(n * (base.is_player() ? 玩家生产倍率 : 电脑生产倍率) / 100.f);

		// 玩家_城市数_惩罚 ('19.5.4)
		if (玩家_城市数_惩罚 and base.is_player() and !pk::is_campaign())
		{
			
			float force_city_count = float(pk::get_city_list(force).count);
			// pk::trace(pk::format("城市数量为{},倍率惩罚{}",force_city_count, (1.f - (force_city_count * 0.01f))));
			n = int(n * (1.f - (force_city_count * 0.02f)));
		}
		// pk::trace(pk::format("3预计生产量为{}",n));

		return n;
	}
}